/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.third.dongjiang.tax.system.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itf.idc.util.ItfRsa;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.WaterMarkUtil;
import org.jeecg.modules.third.dongjiang.tax.system.constant.TaxConstant;
import org.jeecg.modules.third.dongjiang.tax.system.constant.enums.ServiceIdEnum;
import org.jeecg.modules.third.dongjiang.tax.system.dto.ApiBaseResDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.BaseReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.TempTaxpayerDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.TempTaxpayerReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.declaration.DeclarationDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.declaration.DeclarationReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.enterprises.EnterprisesDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.enterprises.EnterprisesReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.invoice.SalesInvoiceDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.invoice.SalesInvoiceReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.order.OrderDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.order.OrderReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.perincomedet.PerincomedetDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.perincomedet.PerincomedetReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.personalincome.PersonalincomeDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.personalincome.PersonalincomeReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.publisher.PublisterDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.publisher.PublisterReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.serviceprovide.ServiceProvideDTO;
import org.jeecg.modules.third.dongjiang.tax.system.dto.req.serviceprovide.ServiceProvideReqDTO;
import org.jeecg.modules.third.dongjiang.tax.system.utils.HttpUtil;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 东疆税务系统
 *
 * @author duanlikao
 * @created 2021/3/12
 */
@Service
@Slf4j
public class DongjiangTaxSystemService {

    @Value(value="${dongjiang-tax-system.domain}")
    private String djTaxApiDomain  ;//= "http://47.105.216.166:8083/idc/";


    @Autowired
    private RedisUtil redisUtil;
    /**
     * 数据校验系统
     */
    private final String  API_VERIFY_SIGN = "/index?url=";

    private final String token = "3bd58ec93b8b94558b6dc4dfaaf71531";

    /**
     * 获取url
     * @param serviceIdEnum
     * @return
     */
    private String getApiUrl(ServiceIdEnum serviceIdEnum){
        if(!ServiceIdEnum.isValid(serviceIdEnum.getCode())){
            return StringUtils.EMPTY;
        }
//       String  verifySign =  StringUtils.isNotEmpty(systemEnvironment) && systemEnvironment.equals("dev") ?
//               API_VERIFY_SIGN+serviceIdEnum.getVerifyPath() : StringUtils.EMPTY;
        return djTaxApiDomain + serviceIdEnum.getCode();
    }

    /**
     * 获取签名
     * @param sys_time 签名时间
     * @return
     */
    private String getSign(String sys_time) throws Exception {
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }

        Object signObject  =  redisUtil.hasKey(TaxConstant.API_TAX_SIGN_KEY) ?
                redisUtil.get(TaxConstant.API_TAX_SIGN_KEY) : null;
        String sign = StringUtils.EMPTY;
        if (signObject == null) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            sys_time = StringUtils.isNotEmpty(sys_time) ? sys_time : sysTime;
            String sign_info = "time:"+sys_time+"@system_id:"+ systemConfig.getDongjiangTaxsystemid() ;
            byte[] sign_info_byte =  sign_info.getBytes("UTF-8");
            byte[] sign_key_byte= ItfRsa.toByteArray(systemConfig.getDongjiangTaxsignkey());
            //获取sign
            byte[] sign_encrypt = ItfRsa.encryptByRSA(sign_key_byte, sign_info_byte);
            if(sign_encrypt.length==0){
                throw new JeecgBootException("获取签名失败,请联系管理员。");
            }
            sign = ItfRsa.toHexString(sign_encrypt);
            redisUtil.set(TaxConstant.API_TAX_SIGN_KEY, sign, TaxConstant.API_TAX_SIGN_KEY_EXPIRE);
            return sign;
        }
        return signObject != null && StringUtils.isNotEmpty(signObject.toString())
                ? signObject.toString() : sign;
    }

    /**
     * 获取系统TaxToken
     * @return
     */
    private String getTaxToken(){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        Object tokenObject  = redisUtil.hasKey(TaxConstant.API_TAX_TOKEN_KEY) ?
                redisUtil.get(TaxConstant.API_TAX_TOKEN_KEY) : null;

        String token = StringUtils.EMPTY;
        if (tokenObject == null ) {
            try {
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String sysTime = df.format(new Date());
                ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_TOKEN.getCode());
                String url = getApiUrl(serviceIdEnum);
                String sign = getSign(sysTime);

                BaseReqDTO baseReqDTO= new BaseReqDTO();
                baseReqDTO.setService_id(ServiceIdEnum.SERVICEID_TOKEN.getCode());
                baseReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
                baseReqDTO.setSign(sign);
                baseReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
                baseReqDTO.setTimestamp(sysTime);
                String jsonString = JSONObject.toJSONString(baseReqDTO);
                log.info("getTaxToken url | {}" ,url);
                log.info("getTaxToken request | {}" ,jsonString);
                String res = HttpUtil.doNewPost(url, jsonString);
                log.info("getTaxToken result | {}" ,res);
                if(StringUtils.isNotEmpty(res)){
                    ApiBaseResDTO result = JSON.parseObject(res, ApiBaseResDTO.class);
                    int code =  StringUtils.isNotEmpty(result.getCode())? Integer.valueOf(result.getCode()) : 0;
                    if( code >= 100 && code < 200  && StringUtils.isNotEmpty(result.getToken())){
                        token =  result.getToken();
                        if(StringUtils.isNotEmpty(token)){
                            redisUtil.set(TaxConstant.API_TAX_TOKEN_KEY, token, TaxConstant.API_TAX_TOKEN_KEY_EXPIRE);
                            return token;
                        }
                    }
                }
            } catch (Exception e) {
                log.info("Exception | {}" ,e.getMessage());
                throw new JeecgBootException(e.getMessage());
            }
        }
        return tokenObject != null && StringUtils.isNotEmpty(tokenObject.toString())
                ? tokenObject.toString() : token;
    }

    /**
     * 企业信息
     * 定时
     * @param enterprisesDTO
     * @return
     */
    public ApiBaseResDTO sendEnterprises(EnterprisesDTO enterprisesDTO){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }

        ApiBaseResDTO apiBaseResDTO = new ApiBaseResDTO();
        if(enterprisesDTO==null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_ENTERPRISES.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendEnterprises token isEmpty ." );
                return apiBaseResDTO;
            }
            EnterprisesReqDTO enterprisesReqDTO = new EnterprisesReqDTO();
            enterprisesReqDTO.setService_id(ServiceIdEnum.SERVICEID_ENTERPRISES.getCode());
            enterprisesReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            enterprisesReqDTO.setSign(sign);
            enterprisesReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            enterprisesReqDTO.setToken(token);
            enterprisesReqDTO.setTimestamp(sysTime);
            enterprisesReqDTO.setPtjbxx(Collections.singletonList(enterprisesDTO));
            String jsonString = JSONObject.toJSONString(enterprisesReqDTO);
//            log.info("sendEnterprises url | {}", url);
//            log.info("sendEnterprises Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
//            log.info("sendEnterprises result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendEnterprises Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());

        }
        return apiBaseResDTO;
    }

    /**
     * 发布方
     * 实时
     * @param publisterDTO
     * @return
     */
    public ApiBaseResDTO sendPublister(PublisterDTO publisterDTO){

        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }

        ApiBaseResDTO apiBaseResDTO = new ApiBaseResDTO();

        if(publisterDTO == null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_PUBLISHER.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendPublister token isEmpty ." );
                return apiBaseResDTO;
            }
            PublisterReqDTO publisterReqDTO = new PublisterReqDTO();
            publisterReqDTO.setService_id(ServiceIdEnum.SERVICEID_PUBLISHER.getCode());
            publisterReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            publisterReqDTO.setSign(sign);
            publisterReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            publisterReqDTO.setTimestamp(sysTime);
            publisterReqDTO.setToken(token);
            publisterReqDTO.setFbfjbxx(Collections.singletonList(publisterDTO));
            String jsonString = JSONObject.toJSONString(publisterReqDTO);
//            log.info("sendPublister url | {}", url);
//            log.info("sendPublister Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
//            log.info("sendPublister result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendPublister Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 服务方
     * 实时
     * @param serviceProvideDTO
     * @return
     */
    public ApiBaseResDTO sendServiceProvide(ServiceProvideDTO serviceProvideDTO){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        ApiBaseResDTO apiBaseResDTO = new ApiBaseResDTO();
        if(serviceProvideDTO == null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_SERVICE_PROVIDE.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendServiceProvide token isEmpty ." );
                return apiBaseResDTO;
            }
            ServiceProvideReqDTO serviceProvideReqDTO= new ServiceProvideReqDTO();
            serviceProvideReqDTO.setService_id(ServiceIdEnum.SERVICEID_SERVICE_PROVIDE.getCode());
            serviceProvideReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            serviceProvideReqDTO.setSign(sign);
            serviceProvideReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            serviceProvideReqDTO.setTimestamp(sysTime);
            serviceProvideReqDTO.setToken(token);
            serviceProvideReqDTO.setFwfjbxx(Collections.singletonList(serviceProvideDTO));
            String jsonString = JSONObject.toJSONString(serviceProvideReqDTO);
            log.info("sendServiceProvide url | {}", url);
//            log.info("sendServiceProvide Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
            log.info("sendServiceProvide result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendServiceProvide Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 订单信息
     * 实时
     * @param orderDTO
     * @return
     */
    public ApiBaseResDTO sendOrder(OrderDTO orderDTO) throws Exception {
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        ApiBaseResDTO apiBaseResDTO = new ApiBaseResDTO();
        if(orderDTO == null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_ORDER.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendOrder token isEmpty ." );
                throw new JeecgBootException("sendOrder token isEmpty .");
            }
            OrderReqDTO orderReqDTO= new OrderReqDTO();
            orderReqDTO.setService_id(ServiceIdEnum.SERVICEID_ORDER.getCode());
            orderReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            orderReqDTO.setSign(sign);
            orderReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            orderReqDTO.setTimestamp(sysTime);
            orderReqDTO.setToken(token);
            orderReqDTO.setDdxx(Collections.singletonList(orderDTO));
            String jsonString = JSONObject.toJSONString(orderReqDTO);
//            log.info("sendOrder url | {}", url);
//            log.info("sendOrder Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
            log.info("sendOrder result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendOrder Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
            throw new JeecgBootException(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 订单服务方(车主)申报数据
     * 申报信息（增值税、印花税、附税）数据
     * 默认按月申报，税务局为方便企业申报便捷操作，
     * 可月底对业务订单按计算规则汇总统计后，
     * 于申报期（非特别通知，默认次月 1 日-10 日）一次性推送
     * @param declarationDTO
     * @return
     */
    public ApiBaseResDTO sendDeclaration(DeclarationDTO declarationDTO){

        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        ApiBaseResDTO  apiBaseResDTO = new ApiBaseResDTO();

        if(declarationDTO == null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_DECLARATION.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendDeclaration token isEmpty ." );
                return apiBaseResDTO;
            }
            DeclarationReqDTO declarationReqDTO = new DeclarationReqDTO();
            declarationReqDTO.setService_id(ServiceIdEnum.SERVICEID_DECLARATION.getCode());
            declarationReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            declarationReqDTO.setSign(sign);
            declarationReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            declarationReqDTO.setTimestamp(sysTime);
            declarationReqDTO.setToken(token);
            declarationReqDTO.setSbxx(Collections.singletonList(declarationDTO));
            String jsonString = JSONObject.toJSONString(declarationReqDTO);
//            log.info("sendDeclaration url | {}", url);
//            log.info("sendDeclaration Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
//            log.info("sendDeclaration result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 个人所得税详细信息
     * 每月定时申报一次
     * @param personalincomeDTO
     * @return
     */
    public ApiBaseResDTO sendPersonalincome(PersonalincomeDTO personalincomeDTO){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        ApiBaseResDTO apiBaseResDTO= new ApiBaseResDTO();

        if(personalincomeDTO == null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_PERSONAL_INCOME.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendPersonalincome token isEmpty ." );
                return apiBaseResDTO;
            }
            PersonalincomeReqDTO personalincomeReqDTO = new PersonalincomeReqDTO();
            personalincomeReqDTO.setService_id(ServiceIdEnum.SERVICEID_PERSONAL_INCOME.getCode());
            personalincomeReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            personalincomeReqDTO.setSign(sign);
            personalincomeReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            personalincomeReqDTO.setTimestamp(sysTime);
            personalincomeReqDTO.setToken(token);
            personalincomeReqDTO.setSdsxx(Collections.singletonList(personalincomeDTO));

            String jsonString = JSONObject.toJSONString(personalincomeReqDTO);
//            log.info("sendPersonalincome url | {}", url);
//            log.info("sendPersonalincome Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
//            log.info("sendPersonalincome result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendPersonalincome Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 个人所得税汇总信息
     * 每月定时申报一次
     * @param perincomedetDTO
     * @return
     */
    public ApiBaseResDTO sendPerincomedet(PerincomedetDTO perincomedetDTO){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        ApiBaseResDTO  apiBaseResDTO = new ApiBaseResDTO();

        if(perincomedetDTO == null) {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_PERSONAL_INCOME_DETAILED.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendPerincomedet token isEmpty ." );
                return apiBaseResDTO;
            }
            PerincomedetReqDTO perincomedetReqDTO = new PerincomedetReqDTO();
            perincomedetReqDTO.setService_id(ServiceIdEnum.SERVICEID_PERSONAL_INCOME_DETAILED.getCode());
            perincomedetReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            perincomedetReqDTO.setSign(sign);
            perincomedetReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            perincomedetReqDTO.setTimestamp(sysTime);
            perincomedetReqDTO.setToken(token);
            perincomedetReqDTO.setSdshzxx(Collections.singletonList(perincomedetDTO));
            String jsonString = JSONObject.toJSONString(perincomedetReqDTO);
//            log.info("sendPerincomedet url | {}", url);
//            log.info("sendPerincomedet Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
//            log.info("sendPerincomedet result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendPerincomedet Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 增值税销项发票
     * 平台给货主发票
     * @param salesInvoiceDTOS
     * @return
     */
    public ApiBaseResDTO sendSalesInvoice( List<SalesInvoiceDTO> salesInvoiceDTOS){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }
        ApiBaseResDTO  apiBaseResDTO = new ApiBaseResDTO();
        if( CollectionUtils.isEmpty( salesInvoiceDTOS) ){
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_SALES_INVOICE.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendSalesInvoice token isEmpty ." );
                return apiBaseResDTO;
            }
            SalesInvoiceReqDTO salesInvoiceReqDTO = new SalesInvoiceReqDTO();
            salesInvoiceReqDTO.setService_id(ServiceIdEnum.SERVICEID_SALES_INVOICE.getCode());
            salesInvoiceReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            salesInvoiceReqDTO.setSign(sign);
            salesInvoiceReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            salesInvoiceReqDTO.setTimestamp(sysTime);
            salesInvoiceReqDTO.setToken(token);
            salesInvoiceReqDTO.setFpxx(salesInvoiceDTOS);
            String jsonString = JSONObject.toJSONString(salesInvoiceReqDTO);
            log.info("sendSalesInvoice url | {}", url);
            log.info("sendSalesInvoice Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
            log.info("sendSalesInvoice result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendSalesInvoice Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());
        }
        return apiBaseResDTO;
    }

    /**
     * 推送临时纳税人登记信息
     * @param tempTaxpayerDTO
     * @return
     */
    public ApiBaseResDTO sendTempTaxpayer(TempTaxpayerDTO tempTaxpayerDTO){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getDongjiangIzUse()){
            throw new JeecgBootException("天津东疆税务上报服务暂未开启,请联系管理员。");
        }

        ApiBaseResDTO apiBaseResDTO = new ApiBaseResDTO();
        if(tempTaxpayerDTO==null)  {
            return apiBaseResDTO;
        }

        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sysTime = df.format(new Date());
            ServiceIdEnum serviceIdEnum = ServiceIdEnum.getServiceIdEnumByVal(ServiceIdEnum.SERVICEID_TEMPORARY_TAXPAYER.getCode());
            String url = getApiUrl(serviceIdEnum);
            String sign = getSign(sysTime);

            String token = getTaxToken();
            if(StringUtils.isEmpty(token)){
                log.info("sendTempTaxpayer token isEmpty ." );
                return apiBaseResDTO;
            }
            TempTaxpayerReqDTO tempTaxpayerReqDTO = new TempTaxpayerReqDTO();
            tempTaxpayerReqDTO.setService_id(ServiceIdEnum.SERVICEID_TEMPORARY_TAXPAYER.getCode());
            tempTaxpayerReqDTO.setSystem_id(systemConfig.getDongjiangTaxsystemid());
            tempTaxpayerReqDTO.setSign(sign);
            tempTaxpayerReqDTO.setSeq(UUID.randomUUID().toString().replace("-", ""));
            tempTaxpayerReqDTO.setToken(token);
            tempTaxpayerReqDTO.setTimestamp(sysTime);
            tempTaxpayerReqDTO.setLsNsrDjxx(Collections.singletonList(tempTaxpayerDTO));
            String jsonString = JSONObject.toJSONString(tempTaxpayerReqDTO);
            log.info("sendTempTaxpayer url | {}", url);
            log.info("sendTempTaxpayer Request | {}", jsonString);
            String res = HttpUtil.doNewPost(url, jsonString);
            log.info("sendTempTaxpayer result | {}" , res);
            if(StringUtils.isNotEmpty(res)){
                return JSON.parseObject(res, ApiBaseResDTO.class);
            }
        } catch (Exception exception) {
            log.info("sendTempTaxpayer Exception |{}" ,exception.getMessage());
            apiBaseResDTO.setCode("0");
            apiBaseResDTO.setDesc(exception.getMessage());

        }
        return apiBaseResDTO;
    }

    /**
     * test接口
     */
    static void testEnterprises(){
        //1.平台基本信息
        EnterprisesDTO enterprisesDTO = new EnterprisesDTO();
        enterprisesDTO.setNsrmc("河北巨睿物流科技有限公司");//  是 纳税人名称
        enterprisesDTO.setNsrsbh("91130582MA0DGPP544");// 是 纳税人识别号
        enterprisesDTO.setHy("5431");// 道路货物运输//是 行业-填写行业代码，参 见《行业代码-名称表》2019-5-15 说明
        enterprisesDTO.setZgswskfj("沙河市税务局城区税务分局");// 是 主管税务所（科、分局）**********
        enterprisesDTO.setNsrzt("正常");// 是 纳税人状态（默认填写： 正常）
        enterprisesDTO.setZcdz("河北省邢台市沙河市新城镇小屯桥村北300米");// 是 注册地址
        enterprisesDTO.setZgswjg("国家税务总局沙河市税务局");// 是 主管税务局**********
        enterprisesDTO.setFddbrxm("霍朋飞");// 是 法定代表人姓名
        enterprisesDTO.setScjydzxzqh("130582");// 是 生产经营地址行政区划- 填写行政区划代码（市 级），参见《行政区划 代码-名称表》 2019-5-15 说明
        enterprisesDTO.setZcdzxzqh("130582");// 是 注册地址行政区划-填写 行政区划代码（市级）， 参见《行政区划代码- 名称表》 2019-5-15 说明
        enterprisesDTO.setJdxz("河北省邢台市沙河市");// 是 街道乡镇
        enterprisesDTO.setScjydz("河北省邢台市沙河市新城镇小屯桥村北300米");// 是 生产经营地址
        enterprisesDTO.setJyfw("网上信息发布服务；增值电信业务；普通货运（网络货运）；仓储服务（不含危险化学品）；搬运装卸服务；物流信息咨询服务（金融、类金融信息咨询除外）；配货信息服务；货物运输代理；国内广告设计、发布；汽车（不含观光车、老年代步车）、二手车信息咨询及销售；润滑油（不含刹车油）、汽车用防冻液（不含危险化学品）、汽车配件、汽车用装饰品、轮胎销售；物流软件技术研发、技术推广、技术装让、技术咨询、技术服务（依法须经批准的项目，经相关部门批准后方可开展经营活动）###");// 是 经营范围
        enterprisesDTO.setFddbrsfzjzl("201");// 是 法定代表人身份证件种 类-填写身份证件种类代 码，参见《申报表-计税 excel 页签：证件代码表》2019-5-15 说明
        enterprisesDTO.setFddbrsfzjhm("130582198404032410");// 是 法定代表人身份证号码
        enterprisesDTO.setCwfzrsfzjzl("201");// 是 财务负责人身份证件种 类-填写身份证件种类代 码，参见《申报表-计税 excel 页签：证件代码表》2019-5-15 说明
        enterprisesDTO.setCwfzrsfzjhm("130582198404032410");// 是 财务负责人身份证件号 码
        enterprisesDTO.setCwfzrgddh("13513295900");// 是 财务负责人固定电话
        enterprisesDTO.setCwfzryddh("13513295900");// 是 财务负责人移动电话
        enterprisesDTO.setBsrxm("申路航");// 是 办税人姓名
        enterprisesDTO.setBsrsfzjzl("201");// 是 办税人身份证件种类-填 写身份证件种类代码，参 见《申报表-计税 excel 页签：证件代码表》
        enterprisesDTO.setBsrgddh("15531930222");// 是 办税人固定电话
        enterprisesDTO.setBsryddh("15531930222");// 是 办税人移动电话
        enterprisesDTO.setZczb("壹仟万元整");// 是 注册资本
        enterprisesDTO.setBsrsfzjhm("130582198612192451");// 是 办税人身份证件号码
        enterprisesDTO.setSwdlrmc("");//*********************** 否 税务代理人名称
        enterprisesDTO.setCwfzrdzxx("411156961@qq.com");// 是 财务负责人电子信箱
        enterprisesDTO.setBsrdzxx("424399211@qq.com");// 是 办税人电子信箱
        enterprisesDTO.setCyrs("5");// 是 从业人数
        enterprisesDTO.setFddbrgddh("13513295900");// 是 法定代表人固定电话
        enterprisesDTO.setFddbryddh("13513295900");// 是 法定代表人移动电话
        enterprisesDTO.setCwfzrxm("申路航");// 是 财务负责人姓名
        enterprisesDTO.setFddbrdzxx("411156961@qq.com");// 是 法定代表人电子信箱 2019-7-22 新增
        enterprisesDTO.setWz("http://www.hbjrect.com");// 是 网址 2019-7-22 新增
        enterprisesDTO.setNsrywmc("");//*********************** 否 纳税人英文名称 2019-7-22 新增
        ApiBaseResDTO apiBaseResDTO  =  new DongjiangTaxSystemService().sendEnterprises(enterprisesDTO);
        System.out.println("1.平台基本信息接口调用:" + apiBaseResDTO);
    }
    static void testPublister(){
        //2.发布方（货主）信息
        PublisterDTO publisterDTO = new PublisterDTO();
        publisterDTO.setFbfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "1367660937405796355");// 是 平台生成的发布方唯一标识 （uuid 默认长度 32 位，建议 以平台缩写大写字母作为前 缀，并结合数字+字母混合形成 32 位唯一标识）
        publisterDTO.setFbfxm("霍永斌");// 否 发布方（货主）姓名 2019-7-9 说明
        publisterDTO.setFbfsfzjhm("132222195902012418");// 否 发布方（货主）身份证件号码 2019-7-9 说明
        publisterDTO.setYddh("");// 否 手机号码 2019-7-9 说明
        publisterDTO.setGjdq("");// 否 国籍（地区）-填写国家地区 代码，参见《申报表-计税 excel 页签：国家和地区代 码》 2019-7-9 说明
        publisterDTO.setQyyddh("13932943666");// 是 企业手机电话号码
        publisterDTO.setNsrsbh("91130582347788159F");// 是 企业纳税人识别号
        publisterDTO.setNsrmc("沙河市中润贸易有限公司");// 是 企业名称（纳税人名称）
        publisterDTO.setGsdz("河北省邢台市沙河市");// 是 公司地址
        publisterDTO.setXxdz("河北省邢台市沙河市新城镇小屯桥村西329省道（小屯桥加油站西侧）");// 是 详细地址
        publisterDTO.setFddbr("常东飞");// 是 法定代表人
        publisterDTO.setZczb("500万");// 是 注册资本
        publisterDTO.setSlrq("2015-08-05");// 是 成立日期
        publisterDTO.setSsdq("130582");// 是 所属地区-填写行政区划代 码（市级），参见《行政区划 代码-名称表》 2019-5-1 0 新增 2019-5-1 5 说明
        publisterDTO.setJyfw("粉煤灰、砂石料销售;白云石、石膏、水泥、水泥熟料、铁精粉、铁矿石、石灰石粉、矿粉、电炉渣、石英砂、涂衬砂、石子、资土、方\n"
                + "解石、石灰石、化工产品(不含危险化学品)、石材销售:建材销售:橡胶制品、汽车配件、轮胎、钢材(不含地条钢)、五金工具，办公设备、机电设备、电线电缆、机械设备配件、计算机软件及辅助设备、劳保用品销售。(依法须经批准项目,经相关部门批准后方可开展经营活动)**\n");// 是 经营范围
        publisterDTO.setPtzcsj("2021-03-05 10:19:12");// 是 企业在平台注册为服务发布 方时间
        publisterDTO.setZgswjg("国家税务总局沙河市税务局第二税务分局");// 是 主管税务机关 2019-5-1 0 新增
        publisterDTO.setNsrlx("1");// 是 企业类型（填写数字代码， 0:一般人/1:小规模） 2019-5-1 0 新增
        String imgStr = "/Users/duanlikao/Downloads/中润营业执照副本 001_1628061845076.jpg";
        String ss = WaterMarkUtil.imageToBase64(imgStr);
        publisterDTO.setYyzzfj(Collections.singletonList(ss));// 是 发布方企业营业执照照片， 照片要求进行 base64转码传输,图片尺寸见补充说明, 图片需要拼接成JSO 数组格式："yyzzfj": ["data:image/jpg;base64, 编码"]
        ApiBaseResDTO apiBaseResDTO  =  new DongjiangTaxSystemService().sendPublister(publisterDTO);
        System.out.println("2.发布方（货主）信息接口调用:"+apiBaseResDTO);
    }
    static void testServiceProvide(){
        //3.服务方（车主）信息
        ServiceProvideDTO serviceProvideDTO = new ServiceProvideDTO();
        serviceProvideDTO.setFwfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "1370191014295244810");// 是 平台生成的服务方唯一标 识（uuid 默认长度 32 位， 建议以平台缩写大写字母 作为前缀，并结合数字+字 母混合形成 32 位唯一标识）
        serviceProvideDTO.setFwfxm("李泽阳");// 是 服务方（车主）姓名
        serviceProvideDTO.setFwfsfzjlx("201");// 是 身份证件类型-填写身份 证件种类代码，参见《申 报表-计税 excel 页签： 证件代码表》 2019-5-15 说明
        serviceProvideDTO.setFwfsfzjhm("130429198304172451");// 是 身份证件号码
        serviceProvideDTO.setYddh("13630897806");// 是 手机号码
        serviceProvideDTO.setJszjhm("130429198304172451");// 是 驾驶证件号码
        serviceProvideDTO.setXszjhm("130500934746");// 是 行驶证件号码(行驶证号 码取行驶证档案编号，如 果行驶证上没有档案编 号 ,可用 vin 代替档案编 号推送为行驶证号码,前 提是传输的行驶证照片 中也没有档案编号) 2019-8-26 说明
        serviceProvideDTO.setCycph("冀ER7448");// 是 承运车牌号
        serviceProvideDTO.setCycx("重型半挂牵引车");// 是 承运车型
        serviceProvideDTO.setCycc("36");// 是 承运车长（数字+单位 m/ 米 长 * 宽 * 高） 7*2*3
        serviceProvideDTO.setCyzz("33.5");// 是 承运载重（数字+单位 t/ 吨）
        serviceProvideDTO.setCypp("豪瀚牌ZZ4255N3847E1L");// 是 承运车辆品牌
        serviceProvideDTO.setCcnf("");// 否 出厂年份 时间格式例如：2019 2019-7-10 说明-选填 标识
        serviceProvideDTO.setJyrq("");// 否 检验日期 2019-7-10 说明-选填 标识
        serviceProvideDTO.setClsyr("沙河市跃轩运输有限公司");// 是 车辆所有人 （自然人、企业） 取行驶证上所有人内容
        serviceProvideDTO.setNsrsbh("");// 否 统一社会信用代码（车主所 在企业的纳税人识别号） 2019-7-10 说明-选填
        serviceProvideDTO.setNsrmc("");// 否 纳税人名称（车主所在企业 名称） 2019-7-10 说明-选填 标识
        serviceProvideDTO.setGsdz("");// 否 公司地址（车主所在企业地 址） 2019-7-10 说明-选填 标识
        serviceProvideDTO.setPtzcsj("2021-03-12 09:52:49");// 20 是 服务方注册时间 系统要求格 式:yyyy-MM-dd HH:mm:ss; 例如 ： 2019-05-21 19:10:10 2019-5-22 说明
        serviceProvideDTO.setSsdq("130525");// 是 服务方所属地区-填写行 政区划代码（市级），参 见《行政区划代码-名称 表》 2019-5-15 说明
        serviceProvideDTO.setZjcx("");// 否 准驾车型（A1、A2、A3、B1、 B2、C1、C2、C3、C4、 M 等） （可暂缓推送） 2019-7-10 说明-选填 标识
        serviceProvideDTO.setJszlqrq("");// 否 领证日期-驾驶证获取日 期，系统要求格 式:yyyy-MM-dd HH:mm:ss; 例如 ： 2019-05-21 19:10:10 2019-7-10 说明-选填 标识
        serviceProvideDTO.setKhrxm("李泽阳");// 是 开户人姓名 2019-5-22 新增
        serviceProvideDTO.setKhrsfzjhm("132226196812020318");// 是 开户人身份证号 （2019-5-22 新增）
        serviceProvideDTO.setKhyh("农业银行");// 是 开户银行(例如光大银行) 2019-5-22 新增
        serviceProvideDTO.setSkzh("6228481259233826578");// 是 银行卡号、微信或支付宝收款账号 2019-5-22 新增

        List imgList1 = new ArrayList();
        imgList1.add(WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/李泽阳1.jpg"));
        imgList1.add(WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/李泽阳2.jpg"));
        serviceProvideDTO.setSmrzfj(imgList1);// 是 司机认证正、反面照片（可推送身份证照片），图片尺寸见补充说明,照片要求进行 base64 转码传输,图片需要拼接成JSON数组格式："smrzfj": ["data:image/jpg;base64 ,正面证件编码 ","data:image/jpg;base6 ,反面证件编码  "

        String imgStr1 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/李泽阳3.jpg");
        List<String> sas = Collections.singletonList(imgStr1);
        serviceProvideDTO.setJszfj(sas);// 是 承运驾驶证照片, 图片尺 寸见补充说明, 照片要求 进行 base64 转码传输,图片 需要拼接成 JSON 数组格式： "jszfj": ["data:image/jpg;base64 ,编码"]

        serviceProvideDTO.setCycsbh("");// 否 车辆识别号代码,行驶证件 vin 号码 2019-7-10 说明-选填 标识
        serviceProvideDTO.setCyczzl("");// 否 总质量（数字+单位） 2019-7-10 说明-选填 标识
        serviceProvideDTO.setCyczbzl("");// 否 整备质量（数字+单位） 2019-7-10 说明-选填 标识
        serviceProvideDTO.setCycsyxz("");// 否 使用性质（填写内容 营 运、非营运） 2019-7-10 说明-选填 标识
        serviceProvideDTO.setCycfdjhm("");// 否 发动机号码 2019-7-10 说明-选填 标识
        serviceProvideDTO.setCyczcsj("");// 否 车辆注册时间 2019-7-10 说明-选填 标识

        serviceProvideDTO.setCycsfgk("否");// 是 是否挂靠车辆 （填写内容是能为： 是/否） ！！！！！ 判断标准 ： 是 ： 行驶证上所有人为 企业或车队等非个人 否 ： 行驶证上所有人为 个人
        serviceProvideDTO.setCycsjsyr("沙河市跃轩运输有限公司");// 是 实际所有人 实际所有人为车主 （即个人，填写个人姓 名，应与服务方姓名，收 款人姓名一致） 2019-5-22 新增
        serviceProvideDTO.setCycsyrlxfs("13630897806");// 是 所有人联系方式 2019-5-22 新增

        String imgStr2 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/李泽阳6.jpg");
        serviceProvideDTO.setCycxszfj(Collections.singletonList(imgStr2));// 是 承运车辆行驶证照片,图 片尺寸见补充说明,照片要求进行 base64 转码传 输,图片需要拼接成 JSON 数组格式："cycxszfj": ["data:image/jpg;base 64,编码"]

        String imgStr3 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/李泽阳5.jpg");
        serviceProvideDTO.setCyczpfj(Collections.singletonList(imgStr3));// 是 承运车辆照片, 图片尺 寸见补充说明,照片要求 进行 base64 转码传输,图 片需要拼接成 JSON 数组 格式："cyczpfj": ["data:image/jpg;base 64,编码"]

        String imgStr4 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/车辆挂靠声明_20210816143826_1.jpg");
        serviceProvideDTO.setCzsmgkfj(Collections.singletonList(imgStr4));// 是 车主声明-车辆所有人为 个人附件照片, 是/否要 求 及 图片尺寸见补充 说明,照片要求进行 base64 转码传输,图片需 要拼接成 JSON 数组格式： "czsmgkfj": ["data:image/jpg;base 64,编码"]
        serviceProvideDTO.setQysmgkfj("");// 是 挂靠企业声明-车辆仅做 挂靠处理附件照片, 是/ 否要求 及 图片尺寸见 补充说明,照片要求进行 base64 转码传输,图片需 要拼接成 JSON 数组格式： "qysmgkfj": ["data:image/jpg;base 64,编码"]
        ApiBaseResDTO a  =  new DongjiangTaxSystemService().sendServiceProvide(serviceProvideDTO);
        System.out.println("3.服务方（车主）信息接口调用:" + a);
    }
    /**
     * fdsj < jdsj < qsfwsj < jsfwsj < jssj
     * 1) 发单时间（fdsj）2021-03-13 14:17:14
     * 2) 接单时间（jdsj）2021-03-14 10:31:52
     * 3) 装货时间（qsfwsj）2021-03-14 12:13:09
     * 4) 卸货时间（jsfwsj）2021-03-15 11:48:23
     * 5) 结算时间（jssj）2021-03-16 10:02:56
     */
    static void testOrder() throws Exception {
        //4.业务订单数据元素
        OrderDTO orderDTO = new OrderDTO();
        orderDTO.setDdbh(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "DD2021081000001");// 是 发布方订单编号（ddbh 默 认长度 32 位，建议以平台 缩写大写字母作为前缀， 并结合数字+字母混合形 成 32 位唯一标识）
        orderDTO.setDduuid("1370619942205919233");// 是 订单唯一标识，由平台生 成订单唯一标识，在服务 方订单中需要使用该唯一 标识（uuid 默认长度 32 位，建议以平台缩写大写 字母作为前缀，并结合数 字+字母混合形成 32 位唯 一标识）
        orderDTO.setFbfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "1367660937405796355");// 是 对应发布方唯一标识 货主 fbfuuid
        orderDTO.setFbfxm("");// 否 发布方联系人姓名
        orderDTO.setFbfsfzjhm("");// 否 发布方联系人身份证件号 码
        orderDTO.setFbfnsrmc("沙河市中润贸易有限公司");// 是 发布方企业名称
        orderDTO.setFbfnsrsbh("91130582347788159F");// 是 发布方企业纳税人识别号
        orderDTO.setFdsj("2021-08-13 14:17:14");//1 是 发单时间（2019-03-20 14:54:31）
        orderDTO.setJdsj("2021-08-14 10:31:52");//2 是 接单时间-服务方接单 签订协议时间（时间格 式：yyyy-MM-dd HH：mm： ss 例如 ：2019-06-25 09:32:43 ） 2019-5-25 说明
        orderDTO.setFdfs("PC");// 是 发单方式（PC、手机）
        orderDTO.setFbfddje(String.valueOf(106500.00));// (18,2 ) 是 发布方（货主）订单金 额
        orderDTO.setFwfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "1370191014295244810");// 是对应服务方唯一标识 司机 fwfuuid
        orderDTO.setFwfxm("李泽阳");// 是 服务方（车主）姓名
        orderDTO.setFwfsfzjlx("201");// 是 身份证件类型-填写身 份证件种类代码，参见 《申报表-计税 excel页 签：证件代码表》 2019-5-15 说明
        orderDTO.setFwfsfzjhm("130429198304172451");// 是 服务方（车主）身份证 件号码
        orderDTO.setFwsj("1天");// 是 起点到终点间运输服务 时长（以小时为单位， 比如 1小时、1天 3小时） （2019-5-10 说明） 2019-5-10 说明
        orderDTO.setQsfwsj("2021-08-14 12:13:09");//3 是 起始运输时间-运输货物发车时间 2019-5-10
        orderDTO.setJsfwsj("2021-08-15 11:48:23");//4 是 结束运输时间-车辆到 达目的地时间 2019-5-10 说明2019-7-9 新增
        orderDTO.setSfd("130500");// 是 起运地（始发地）-填写 行政区划代码（市级）， 参见《行政区划代码-名 称表》 2019-5-15 说明
        orderDTO.setMdd("130400");// 是 到达地（目的地）-填写 行政区划代码（市级）， 参见《行政区划代码-名 称表》 2019-5-15 说明
        orderDTO.setSfdxxdz("河北省邢台市柏乡县内步乡北大江村村北");// 是 始发地详细地址
        orderDTO.setMddxxdz("河北省邯郸市武安市2672工业区新兴铸管股份有限公司");// 是 目的地详细地址
        orderDTO.setCc(String.valueOf(36.00));// (18,2 ) 是 车长（数量+单位 m/米 长*宽*高）
        orderDTO.setCx("重型半挂牵引车");//  是 车型（推送文字）
        orderDTO.setCycph("冀ER7448");//是 承运车牌号 2019-8-2 新增
        orderDTO.setHwzl(String.valueOf(30.00));// (18,2 ) 是 货物重量（t/吨）
        orderDTO.setHwtj(String.valueOf(40.00));// (18,2 ) 是 货物体积（方）
        orderDTO.setHwdw("吨");// 是 货物单位（吨、方）
        orderDTO.setHwmc("重废");// 是 所运货物（货物名称）
        orderDTO.setHyxje(String.valueOf(0.00));// (18,2 ) 是 货运险金额（如果不存 在，默认填写 0） 2020-11-1 说明
        orderDTO.setFwfddje(String.valueOf(2100.00));// (18,2 ) 是 货物运费金额
        orderDTO.setHwsshy("5431");// 是 货物所属行业-填写行 业代码，参见《行业代 码-名称表》 2019-5-15 说明
        orderDTO.setJdfs("手机");// 20 是 接单方式（PC、手机）
        orderDTO.setLc("145.8");// 20 是 路程（公里数）
        orderDTO.setZxfs("一装一卸");// 是 装卸方式（一装一卸 一装两卸）
        orderDTO.setPtfwf(String.valueOf(0.0));// (18,2 ) 是 平台服务费（平台企业自 定，没有默认填写 0） 2020-11-1 说明
        orderDTO.setZk(String.valueOf(0.0));// (18,2 ) 是 货主折扣（平台企业自定， 没有默认填写 0） 2020-11-1 说明
        orderDTO.setZffs("银行卡支付");// 是 支付方式（银行卡支付、 微信支付、支付宝支付、 系统内虚拟货币支付） 2019-5-22 说明
        orderDTO.setHwspbm("");// 否 货物商品编码
        orderDTO.setQtjl("");//否 其他奖励（油费、卡费 等）

        orderDTO.setZfpz("202102221004046767378930092");// 是 支付凭证（支付流水号）
        orderDTO.setYhkh("6228481259233826578");// 是 银行卡号（银行卡号（微 信账号、支付宝账号）） 2019-5-22 说明
        orderDTO.setYhls("资金流水");// 是 银行流水-资金流水

//        List<GpsDTO> gpsDtoList = getListGps("冀ER0085", "2021-03-15 11:48:23");
//        orderDTO.setGps(JSONObject.toJSONString(gpsDtoList));// 是 从货物运输发车开始到 目的地之间的 GPS 或北 斗运输轨迹【GPS 统一标 准为火星坐标系 (GCJ-02) 】,推送数据 需拼接成 json数组格式 后，转成字符串推送： "gps":"[{\"lat\":\"3 8.538010368599704\", \"lon\":\"112.068393 46026618\",\"positio nTime\":\"2019-07-03 10:19:01\"},{\"lat\" :\"30.53760840433267 \",\"lon\":\"104.068 57044530535\",\"posi tionTime\":\"2019-07 -0310:22:58\"},…]" 2019-7-9 说明
        orderDTO.setGps("");// 是 从货物运输发车开始到 目的地之间的 GPS 或北 斗运输轨迹【GPS 统一标 准为火星坐标系 (GCJ-02) 】,推送数据 需拼接成 json数组格式 后，转成字符串推送： "gps":"[{\"lat\":\"3 8.538010368599704\", \"lon\":\"112.068393 46026618\",\"positio nTime\":\"2019-07-03 10:19:01\"},{\"lat\" :\"30.53760840433267 \",\"lon\":\"104.068 57044530535\",\"posi tionTime\":\"2019-07 -0310:22:58\"},…]" 2019-7-9 说明

        orderDTO.setDdjsssqy("");// 否 订单接收所属区域
        orderDTO.setJssj("2021-08-16 10:02:56");//5 是 订单结束时间-最终结算时间 时间格式：yyyy-MM-dd HH:mm:ss 2019-5-10 新增
        orderDTO.setSkrxm("李泽阳");// 是 收款人姓名，指订单完 成时，收到款项的人的 姓名 2019-7-9 说明
        orderDTO.setSkrsfzjhm("130429198304172451");// 是 收款人身份证件号码， 指订单完成时，收到款 项的人的身份证号码 2019-7-9 说明

        String imgStr1 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/运单2.png");
        orderDTO.setXczhfj(Collections.singletonList(imgStr1));// 是 现场装货照片, 图片尺寸见补充说明,照片要 求进行 base64 转码传 输,图片需要拼接成 JSON 数组格式： "xczhfj": ["data:image/jpg;bas e64,编码"]
        String imgStr2 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/运单4.png");
        orderDTO.setXcxhfj(Collections.singletonList(imgStr2));// 是 现场卸货照片, 图片尺 寸见补充说明,照片要 求进行 base64 转码传 输,图片需要拼接成 JSON 数组格式： "xcxhfj": ["data:image/jpg;bas e64,编码"] 2019-7-9 新增
        String imgStr3 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/运单1.jpg");
        orderDTO.setThdfj(Collections.singletonList(imgStr3));// 是 提货单, 图片尺寸见补 充说明,照片要求进行 base64 转码传输,图片 需要拼接成JSON数组格 式："thdfj": ["data:image/jpg;bas e64,编码"] 2019-7-9 新增
        String imgStr4 = WaterMarkUtil.imageToBase64("/Users/duanlikao/Downloads/运单3.jpg");
        orderDTO.setRkdfj(Collections.singletonList(imgStr4));// 是 入库单, 图片尺寸见补 充说明,照片要求进行 base64 转码传输,图片 需要拼接成JSON数组格 式："rkdfj": ["data:image/jpg;base64,编码"]

        ApiBaseResDTO a = new DongjiangTaxSystemService().sendOrder(orderDTO);
        System.out.println("4.业务订单数据元素接口调用:" + a);
    }
    static void testDeclaration(){
        //5.订单服务方(车主)申报数据元素
        DeclarationDTO declarationDTO = new DeclarationDTO();
        declarationDTO.setFwfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "1370191014295244810");// 是 对应服务方唯一标识 fwfuuid
        declarationDTO.setBdzdwnsrsbh("130429198304172451");// 是 被代征单位纳税人识别号 （被代征人的身份证号）
        declarationDTO.setBdzdwnsrmc("李泽阳");// 是 被代征单位纳税人名称 （被代征人的姓名）
        declarationDTO.setBdzcbsbh("");// 否 被代征船舶识别号
        declarationDTO.setBdzcbmc("");// 否 被代征船舶名称
        declarationDTO.setGjhdq("156");// 是 国家或地区-填写被代征 人国家地区代码，参见《申 报表-计税 excel 页签：国 家和地区代码》 （默认：156） 2019-5-15 说明
        declarationDTO.setZjlx("201");// 是 证件类型（被代征人） 身份证件类型-填写身份 证件种类代码，参见《申 报表-计税 excel 页签：证 件代码表》 2019-5-15 说明
        declarationDTO.setZjhm("130429198304172451");// 是 证件号码（被代征人）
        declarationDTO.setSshy("5431");// 是 所属行业（-填写平台企业 所在行业代码，参见《行 业代码-名称表》） 正式接入后，需与代征协议 签订的所属行业（经营范 围）一致
        declarationDTO.setZsxm("30216");//  是 征收项目（按平台核定）  申报表各税种对应征 收项目代码： 申报税种 征收项目 代码 增值税 10101 印花税 10111 城建税 10109 教育附加 税 30203 地方教育 附加税 30216
        declarationDTO.setZspm("302160100");// 是 征收品目（按平台核定）
        declarationDTO.setZszm("");// 是 征收子目
        declarationDTO.setSkssqq("2021-08-01");// 是 税款所属期起，到日，月份 第一天（例：2020-01-01） 2020-11-1 说明
        declarationDTO.setSkssqz("2021-08-30");// 是 税款所属期止，到日，月份 最后一天（例： 2020-01-31） 2020-11-1 说明
        // (18, 2) 是 计税依据 数额界限：当月收入 /1.03>10 万（
        //  无税时 计税依据=当 月收入/1.03
        //  有税时 计税依据=当 月收入/1.03）
        //印花税是原收入 不用/1.03 119126.21
        //无税时，减免性质代码只填写增值税和印花税的，其余三个附税不填。 92700.00 122700.00
        declarationDTO.setJsyj(String.valueOf(1214.85));
        // (20, 4) 是 税率或税额 （按各税种执行：
        // 1 增值税 ：3%
        // 2 运输印花税 ： 万分之五 ③技术印花税 ： 万分之 三（印花税跟局方【税政管理三科】确认）
        // 3 城建税 ：7%
        // 4 教育费附加 ：3%
        // 5 地方教育附加 ：2%）
        declarationDTO.setSlhse(String.valueOf(0.0200));
        declarationDTO.setYnse(String.valueOf(24.30));// (18, 2) 是 应纳税额 (计税依据 * 对应税种税率)
        declarationDTO.setJmse(String.valueOf(12.15));// (18, 2) 是 减免税额 （有税申报时：减免税额 =0；无税申报时：减免税额 = 应纳税额） 根据财税 201913 号文件规定 减免税额有最新优惠政策，参考后文样例
        declarationDTO.setYdzse(String.valueOf(12.15));// (18, 2) 是 应代征税额 （应纳税额 - 减免税额）
        declarationDTO.setYjse(String.valueOf(0.00));// (18, 2) 是 已缴税额（默认填写 0） 2020-12-1 说明
        declarationDTO.setSdzse(String.valueOf(0.00));// (18, 2) 是 已代征税额（默认填写 0） 2020-12-1 说明
        declarationDTO.setSybz("");// 否 税源标志
        declarationDTO.setSybh("");// 否 税源编号
        declarationDTO.setSyzl("");// 否 税源坐落
        declarationDTO.setJmxz("0099049901");// 是 减免性质（减免代码）
        ApiBaseResDTO a = new DongjiangTaxSystemService().sendDeclaration(declarationDTO);
        System.out.println("5.订单服务方(车主)申报数据元素接口调用:" + a);
    }
    static void testPersonalincome(){
        //6.个人所得税申报所需明细数据元素
        PersonalincomeDTO personalincomeDTO = new PersonalincomeDTO();

        personalincomeDTO.setNsrsbh("91120118MA07DR024P");// 是 纳税人识别号（平台企业）
        personalincomeDTO.setNsrmc("河北巨睿物流科技有限公司天津分公司");// 是 纳税人名称（平台企业）
        personalincomeDTO.setHy("5431");// 是 行业（平台企业）-填写行 业代码，参见《行业代码- 名称表》 2019-5-15 说明
        personalincomeDTO.setXzqh("120116");// 是 行政区划（平台企业）- 填写行政区划代码（市 级），参见《行政区划代码 -名称表》 （默认：120116） 2019-5-15 说明
        personalincomeDTO.setJdxz("天津自贸试验区（东疆保税港区）");// 是 街道乡镇（平台企业）
        personalincomeDTO.setSwjg("天津市东疆保税港区国家税务局");// 是 税务机关（平台企业）

        //司机
        personalincomeDTO.setFwfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX + "1370191014295244810");// 是 对应服务方唯一标识 fwfuuid
        personalincomeDTO.setSfzjlx("201");// 是 身份证件类型（自然人）- 填写身份证件种类代码， 参见《申报表-计税 excel 页签：证件代码表》
        personalincomeDTO.setSfzjhm("130429198304172451");// 是 身份证件号码（自然人）
        personalincomeDTO.setXm("李泽阳");// 是 姓名（自然人）
        personalincomeDTO.setGjdq("156");// 是 国籍（地区）（自然人）- 填写国家地区代码，参见 《申报表-计税 excel 页 签：国家和地区代码》 （默认填写：156） 2019-5-15 说明
        personalincomeDTO.setLxdh("13630897806");// 是 联系电话（自然人）
        personalincomeDTO.setScjydxzqh("120116");// 是 生产经营地行政区划（至 省、直辖市，取个人当年 第一次申报所属行政区 划）（自然人默认填写 120116（东疆行政区划））

        personalincomeDTO.setSbrq("2021-08-01");// 是 申报日期
        personalincomeDTO.setSkssqq("2021-07-01");// 是 税款所属期起。到月份第 一天（例：2020-01-01）
        personalincomeDTO.setSkssqz("2021-07-31");// 是 税款所属期止。到月份最 后一天（例：2020-01-31）
        // (18,2 ) 是 应税收入(自然人当年累 计收入) 计算方式：从当年 1 月份 到本月的应税收入累计，其中每月的应税收入计算 规则为：
        //  如果该月份订单累计 金额/1.03<=10W 则该 月应税收入为订单累 计金额；
        //  如果该月份订单累计 金额/1.03>10W 则该 月应税收入为订单累 计金额/1.03；
        //无税时是原收入 不用/1.03
        personalincomeDTO.setYssr( String.valueOf(92700.00) );
        personalincomeDTO.setYssdl(String.valueOf(0.05));// (18,2 ) 是 应税所得率 默认 5%，如有变更，以最 新政策为准 2020-5-1 说明
        personalincomeDTO.setJsyj(String.valueOf(4635.00));// (18,2 ) 是 计税依据 (应税收入 * 应税所得率)
        personalincomeDTO.setSl(String.valueOf(0.05));// (18,2 ) 是 税率(需将百分比换算成小数) (速算表)
        personalincomeDTO.setSskcs(String.valueOf(0.00));// (18,2 ) 是 速算扣除数 (生产经营所得) 速算表
        personalincomeDTO.setYnse(String.valueOf(231.75));// (18,2 ) 是 应纳税额 (计税依据 * 速算表税率 - 速算扣除数)
        // (18,2 ) 是 累计已缴税额 （之前各月已缴纳个税总 和例如：
        //  一月设为当年初始申 报，默认为零
        //  二月为一月份的应缴 纳个税金额（即 1 月 份的本期应补退税 额，若该自然人一月 未申报则为 0）
        //  三月份为一月份与二 月份的应缴纳个税金 额累计（即 1 月份的 本期应补退税额+2 月 份的本期应补退税 额。
        // 若之前该用户全 未申报个税则为 0，否 则累计）其他月份以此类推
        personalincomeDTO.setLjyjse(String.valueOf(0.00));
        personalincomeDTO.setBqybtse(String.valueOf(231.75));// (18,2 ) 是 本期应补退税额 （应纳税额 - 累计已缴税额）
        ApiBaseResDTO a = new DongjiangTaxSystemService().sendPersonalincome(personalincomeDTO);
        System.out.println("6.个人所得税申报所需明细数据元素接口调用:" + a);
    }
    static void testPerincomedet(){
        //7.个人所得税申报所需汇总数据元素
        PerincomedetDTO perincomedetDTO = new PerincomedetDTO();
        perincomedetDTO.setSkssqq("2021-07-01");// 是 税款所属期起
        perincomedetDTO.setSkssqz("2021-07-31");// 是 税款所属期止
        perincomedetDTO.setSbrq("2021-08-01");// 是 申报日期

        perincomedetDTO.setNsrsbh("91120118MA07DR024P");// 是 扣缴义务人识别号（平台 企业-纳税人社会信用代 码）
        perincomedetDTO.setNsrmc("河北巨睿物流科技有限公司天津分公司");// 是 扣缴义务人名称（平台企 业-纳税人名称）

        perincomedetDTO.setSl(String.valueOf(0.05));// (18,2) 是 税率（5%、10%、20%、30%、 35%）（以个税明细申报 表为基础，按税率进行汇 总）
        perincomedetDTO.setSbrs(String.valueOf(1));// 是 申报人数
        // (18,2) 是 应税收入 汇总中的所有数值均以明细汇总而来，汇总以税率进行区分，同税率的进行 汇总，例如： 假设税率=5%，那么： 5%汇总的 yssr = 5%明细 1 的 yssr + 5%明细 2 的 yssr。 以此类推。
        perincomedetDTO.setYssr(String.valueOf(92700.00));
        perincomedetDTO.setYnse(String.valueOf(231.75));// (18,2) 是 应纳税额 (月收入/1.03*0.05 * 速算表税率 - 速算扣除数)
        perincomedetDTO.setLjyjnse(String.valueOf(0.00));// (18,2) 是 累计已缴纳税额
        perincomedetDTO.setBqybtse(String.valueOf(231.75));// (18,2) 是 本期应补退税额 =应纳税额
        ApiBaseResDTO a  =  new DongjiangTaxSystemService().sendPerincomedet(perincomedetDTO);
        System.out.println("7.个人所得税申报所需汇总数据元素接口调用:" + a);
    }
    public static void main(String[] args) {




//        testEnterprises();
//        testPublister();
//        testServiceProvide();
//        testOrder();
//        testDeclaration();
//        testPersonalincome();
//        testPerincomedet();
	}

}
